package com.hsck.order.kds.base.utils

import android.annotation.SuppressLint
import android.speech.tts.TextToSpeech
import android.speech.tts.UtteranceProgressListener
import android.util.Log
import com.hjq.toast.Toaster
import com.hsck.order.kds.AppApplication
import com.hsck.order.kds.R
import java.util.Locale
import kotlin.math.min

/**
 * @author isnoam
 * @package_name TextToSpeechManager
 * @date 2024-09-24
 * @description：文本阅读（TTS） 管理器
 */
class TextToSpeechManager() : TextToSpeech.OnInitListener {

    private var ttsErrorStatus: Int = 0
    private var tts: TextToSpeech? = null

    init {
        tts = TextToSpeech(AppApplication.context, this)
    }

    /**
     * 设置音调，值越大声音越尖（女生），值越小则变成男声，默认值为 1.0
     */
    fun setPitch(pitch: Float) {
        val tts = tts ?: return
        tts.setPitch(pitch)
    }

    /**
     * 设置语速，默认值为 1
     */
    fun setSpeechRate(rate: Float) {
        val tts = tts ?: return
        tts.setSpeechRate(rate)
    }

    /**
     * 读文本
     * @param content 文本内容
     * @param utteranceProgressListener 阅读进度监听
     */
    fun speak(
        content: String,
        utteranceProgressListener: GetLastSegUtteranceProgressListener,
    ) {
        val tts = tts ?: return
        tts.setOnUtteranceProgressListener(utteranceProgressListener)
        when (ttsErrorStatus) {
            TextToSpeech.LANG_MISSING_DATA -> Toaster.showShort(R.string.voice_missing_data)
            TextToSpeech.LANG_NOT_SUPPORTED -> Toaster.showShort(R.string.voice_lang_not_supported)
            ANDROID_VERSION_NOT_SUPPORT -> Toaster.showShort(R.string.voice_android_version_not_supported)
            else -> {
                if (tts.isSpeaking) {
                    tts.stop()
                } else {
                    val textSeg = genSegment(content, 10)
                    utteranceProgressListener.setLastSegId(SEG_PREFIX + (textSeg.size - 1))
                    for (i in textSeg.indices) {
                        // QUEUE_ADD：播放完之前的语音任务后才播报本次内容，QUEUE_FLUSH：丢弃之前的播报任务，立即播报本次内容
                        tts.speak(textSeg[i], TextToSpeech.QUEUE_ADD, null, SEG_PREFIX + i)
                    }
                }
            }
        }
    }

    /**
     * 将源文本分段
     *
     * @param segmentLength 每一段的长度，最大设置 3999，大于 3999 将阅读出错
     * @param originStr     源文本
     * @return 分成的文本段
     */
    private fun genSegment(originStr: String, segmentLength: Int = 3999): Array<String?> {
        val originLength = originStr.length
        val arraySize = originLength / segmentLength + 1
        val result = arrayOfNulls<String>(arraySize)
        for (i in 0 until arraySize) {
            result[i] =
                originStr.substring(i * segmentLength, min((i + 1) * segmentLength, originLength))
        }
        return result
    }

    /**
     * 取得文本内容大约分钟长度
     */
    fun getSpeechLength(content: String): Int {
        val totalSecond = (content.length / 3.7).toInt()
        return totalSecond / 60
    }

    /**
     * 扩展 onDone 方法的进度监听
     */
    @SuppressLint("NewApi")
    abstract class GetLastSegUtteranceProgressListener : UtteranceProgressListener() {

        private var lastSegId = ""

        /**
         * 设置最后一段的 id
         */
        fun setLastSegId(lastSegId: String) {
            this.lastSegId = lastSegId
        }

        override fun onDone(utteranceId: String?) {
            onDone(utteranceId, lastSegId == utteranceId)
        }

        /**
         * @param isLastSeg 是否是最后一段
         */
        abstract fun onDone(utteranceId: String?, isLastSeg: Boolean)
    }

    companion object {
        private const val SEG_PREFIX = "seg" // 段落前缀
        private const val ANDROID_VERSION_NOT_SUPPORT = -3 // 版本不支持
    }

    override fun onInit(status: Int) {
        //判断是否转化成功
        ttsErrorStatus = status
        //初始化成功后才可以播放
        if (status == TextToSpeech.SUCCESS) {
            //设置语言为中文
            val languageCode = tts!!.setLanguage(Locale.CHINA)
            //判断是否支持这种语言，Android原生不支持中文，使用科大讯飞的tts引擎就可以了
            if (languageCode == TextToSpeech.LANG_NOT_SUPPORTED) {
                Log.d("TAG", "onInit: 不支持这种语言")
            } else {
                //不支持就改成英文
                tts!!.setLanguage(Locale.US)
            }
            //设置音调,值越大声音越尖（女生），值越小则变成男声,1.0是常规
            tts!!.setPitch(1.0f)
            //设置语速
            tts!!.setSpeechRate(1.0f)
            //在onInIt方法里直接调用tts的播报功能
            tts!!.speak("测试播报菜品", TextToSpeech.QUEUE_ADD, null);
        }
    }
}